package com.sudo.boot.admin._wx;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.net.URLEncodeUtil;
import com.boot.starter.redis.component.RedisKeys;
import com.sudo.boot.base.constant.enums.EnumScanLogin;
import com.sudo.boot.mapper.wx.entity.WxUser;
import com.sudo.boot.satoken.util.SaRedisUtil;
import com.sudo.boot.service.wx.WxUserService;
import com.sudo.boot.weixin.config.WxProperties;
import com.sudo.boot.weixin.pojo.WeChatUser;
import com.sudo.boot.weixin.pojo.WeTokenInfo;
import com.sudo.boot.weixin.serivce.Oauth2Service;
import com.sudo.boot.weixin.util.WxUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.Objects;

@Slf4j
@Controller
@RequestMapping("/wx-redirect")
@RequiredArgsConstructor
public class WxRedirectController {

    private final WxUserService wxUserService;
    private final Oauth2Service oauth2Service;
    private final WxProperties wxProperties;
    private final SaRedisUtil saRedisUtil;

    /**
     * 微信绑定或登录
     * 绑定：state为用户ID
     * 登录：state为Login
     */
    @SaIgnore
    @GetMapping("qrcode/callback")
    public String qrCode(@RequestParam("code") String code, @RequestParam("state") String state) {
        // 判断二维码是否过期
        String qrCodeBind = RedisKeys.qrCodeOverdue(state);
        if (Objects.isNull(saRedisUtil.get(qrCodeBind))) {
            return "redirect:" + wxProperties.getQrOverduePage();
        }
        String url;
        if (WxUtil.isLogin(state)) {
            url = loginWxUser(code, state);
        }else {
            url = bindWxUser(code, state);
        }
        return "redirect:" + url;
    }

    private String bindWxUser(String code, String state) {

        String sysUserId = WxUtil.getBindUserId(state);
        log.info("微信二维码绑定授权回调：code={}, state={}", code, state);
        WeTokenInfo weTokenInfo = oauth2Service.getWeTokenInfo(code);
        WeChatUser weChatUser = oauth2Service.getWeChatUser(weTokenInfo.getOpenid(), weTokenInfo.getAccess_token());

        wxUserService.bindWxUser(sysUserId,weChatUser);
        return wxProperties.getBindSuccessPage() +"?nickName=" + URLEncodeUtil.encode(weChatUser.getNickname());
    }

    private String loginWxUser(String code, String state) {
        String loginCode = WxUtil.getLoginCode(state);
        log.info("微信二维码登录授权回调：loginCode={}, loginCode={}", code, loginCode);
        WeTokenInfo weTokenInfo = oauth2Service.getWeTokenInfo(code);
        // 通过openId获取用户信息
        WxUser wxUser = wxUserService.getWxUserByOpenId(weTokenInfo.getOpenid());

        // 设置本次扫码登录会话状态
        String scanLoginStatus = RedisKeys.scanLoginStatus(loginCode);
        if (Objects.isNull(wxUser)) {
            saRedisUtil.set(scanLoginStatus, EnumScanLogin.UNBIND.getCode(),300);
            return wxProperties.getLoginFailPage() +"?msg=" + URLEncodeUtil.encode("您的微信暂未绑定平台账号");
        }
        String scanLoginUserId = RedisKeys.scanLoginUserId(loginCode);
        saRedisUtil.set(scanLoginUserId,wxUser.getSysUserId(),300);
        saRedisUtil.set(scanLoginStatus, EnumScanLogin.LOGIN_SUCCESS.getCode(),300);
        return wxProperties.getLoginSuccessPage() +"?nickName=" + URLEncodeUtil.encode(wxUser.getNickname());
    }

}
